// let array = [1, 'a']   // Array<number | string>

// window.onmousedown = (event) => {
//   console.log(event);
// }

// interface InfoInterface {
//   name: string
// }

// let infos: InfoInterface
// const info1 = { name: 'lison' }
// const info2 = { age: 18 }
// const info3 = { name: 'lison', age: 18 }

// infos = info1
// infos = info3

// 函数的兼容  参数个数, 参数类型 


// 可选参数和剩余参数

// const callback = (...args: number[]): number => args.reduce((a: number, b: number): number => a + b )


// const getSum = (arr: number[],  callback: (...args: number[]) => number): number => {
//   return callback(...arr)
// }

// const aa: number = getSum([1, 2], (...args: number[]): number => args.reduce((a: number, b: number): number => a + b, 0))

// console.log(aa);


// // 函数参数双向协变
// let funcA = (arg: number | string): void => {}
// let funcB = (arg: number): void => {}

// // funcA = funcB   // 会报错 
// funcB = funcA  

// // 返回值类型

// let x = (): string | number => 0
// let y = (): string => 'a'
// let z = (): boolean => false

// x = y
// y = x
// y = z

// 函数重载
// function merge(arg1: number, arg2: number): number
// function merge(arg1: string, arg2: string): string
// function merge(arg1: any, arg2: any){
//   return arg1 + arg2
// } 

// enum StatusInterface {
//   On, 
//   Off,
// }

// let s = StatusInterface.On
// s = 2 // 数字类型

// enum StatusEnum {
//   On,
//   Off,
// }

// enum AnimalEnum {
//   Dog,
//   Cat,
// }

// let s = StatusEnum.On
// // s = AnimalEnum.Dog  //两个枚举是不兼容的

// class AnimalClasss {
//   public static age: number
//   constructor(public name: string) {
//     this.name = name
//   }
// }
// class PeopleClass {
//   public static age: string
//   constructor(public name: string) {
//     this.name = name
//   }
// }
// class FoodIsClass {
//   constructor(public name: number) {
//     this.name = name
//   }
// }

// let animal: AnimalClasss
// let people = PeopleClass
// let food: FoodIsClass

// animal = people  // 可以这样赋值因为他们的构造函数上都有一个 公共name并且name的类型相同
// animal = food  // 会报错， 因为他们的构造函数的name的类型不同

// private 
// protected

// class ParentClass {
//   private age: number |undefined
//   constructor(){}
// }
// class ChildreClass extends ParentClass{
//   constructor() {
//     super()
//   }
// }

// class OtherClass {
//   private age: number | undefined
//   constructor(){}
// }

// const children: ParentClass = new ChildreClass()
// // const other: ParentClass = new OtherClass() // 因为有私有属性所以不能直接这样使用

interface Data<T>{
  // data: T
}
let data1: Data<number>
let data2: Data<string>

// data1 = data2  // 报错
